package cate.game.role.pvp.championrace;

import cate.common.table.d.GDChampionRace;
import cate.common.table.d.GDFunc;
import cate.common.util.GameResult;
import cate.game.pvp.championrace.GameChampionRaceManager;
import cate.game.pvp.championrace.data.ChampionRaceBetRecord;
import cate.game.pvp.championrace.data.ChampionRaceSpec;
import cate.game.pvp.championrace.dto.ChampionRaceRedPacketRecordData;
import cate.game.role.FuncOpenChecker;
import cate.game.role.Role;
import cate.game.role.pvp.championrace.msg.ChampionRaceBetReq;
import cate.game.role.pvp.championrace.msg.ChampionRaceLiteDataResp;
import cate.game.role.pvp.championrace.msg.ChampionRaceRedPacketResp;
import cate.game.role.pvp.championrace.vo.ChampionRaceBetVO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import easy.java.dev.note.NoteField;

import java.util.Objects;

import static cate.game.client.msg.MsgSender.send;

public class RoleChampionRace extends FuncOpenChecker {
    @NoteField("最吊排名")
    public int topRank;
    @NoteField(value = "当前赛季")
    public int season;

    @JsonIgnore
    @NoteField("竞猜数据")
    public ChampionRaceBet bet;

    @NoteField("红包数据")
    public ChampionRaceRedPacket redPacket;

    public boolean notice;

    @NoteField(value = "当前赛季开启时间")
    public long seasonStartTime;

    @NoteField(value = "下个赛季开启的时间")
    public long nextSeasonStartTime;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (Objects.isNull(bet)) {
            bet = new ChampionRaceBet();
        }
        bet.initialize(role);
        if (Objects.isNull(redPacket)) {
            redPacket = new ChampionRaceRedPacket();
        }
        redPacket.initialize(role);
    }

    @Override
    public void onEnter() {
        super.onEnter();
//        if (!isOpen()) {
//            return;
//        }
        bet.onEnter();
        redPacket.check(season);
        checkSeason();
    }

    @JsonProperty("betTimes")
    public int getBetTimes() {
        return bet.rdMap.size();
    }

    @JsonProperty("coins")
    public int getCoins() {
        ChampionRaceSpec spec = role.getGame().pvp.championRace.getSpec();
        if (spec == null || spec.getStep() != 1 || bet.hasBet(spec) == 1) {
            return 0;
        }
        return role.getGame().pvp.championRace.getBizHandler().hasRecvdRedPacket(role.getUid()) ? GDChampionRace.FIXED_BET_NUM : 0;
    }

    @Override
    public int getFuncId() {
        return GDFunc.CHAMPION_RACE;
    }

    @Override
    public void onAfterOpen() {
        // 同布人物快照
        role.getRes().crossSync.syncSnapshot();
    }

    public void checkSeason() {
        int serverSeason = game().pvp.championRace.getSeason();
        if (season != serverSeason) {
            onSeasonSwitch(serverSeason);
        }
        this.nextSeasonStartTime = game().pvp.championRace.getNextSeasonStartTime();
        this.seasonStartTime = game().pvp.championRace.getSeasonStartTime();
    }

    private void onSeasonSwitch(int newSeason) {
        this.season = newSeason;
        this.notice = false;
        bet.onSeasonSwitch();
        redPacket.onSeasonSwitch();
    }

    public void handleRedPacketReq() {
        ChampionRaceSpec spec = game().pvp.championRace.getSpec();
        if (bet.rdMap.size() >= GDChampionRace.MAX_BET_TIMES) {
            role.getGame().notice.message(role, "竞猜次数不足，无法领取红包啦");
            return;
        }
        ChampionRaceRedPacketRecordData resp = redPacket.handleRedPacketReq(spec);
        if (resp != null) {
            role.sendNow(new ChampionRaceRedPacketResp(
                    redPacket,
                    resp.data
            ));
        }
    }

    public void handleBetData() {
        bet.handleBetData();
    }

    public void handleBetRwd(ChampionRaceBetRecord betRecord) {
        bet.handleBetRwd(betRecord);
    }

    public void afterBet(ChampionRaceBetVO betVO) {
        bet.handleBet(betVO);
    }

    public void queryBetRecord() {
        bet.queryBetRecord();
    }

    public GameResult<Void> doBet(ChampionRaceBetReq req) {
        GameResult<Void> r = bet.doBet(req.side);
        if (!r.ok()) {
            return r;
        }
        return game().pvp.championRace.getBizHandler().doBet(role, req);
    }

    public void noticeBetData(ChampionRaceSpec spec, ChampionRaceBetRecord record){
        bet.updateNotice(spec, record);
    }

    public void refreshRecord(int rank) {
        if (topRank < 0 || rank < topRank) {
            topRank = rank;
        }
        role.getHistory().action.ChampionRaceRankTimes(rank);
    }

    public void liteNotice() {
//        if (!isOpen()) {
//            return;
//        }
        GameChampionRaceManager gameChampionRaceManager = role.getGame().pvp.championRace;
        send(role::sendNow, new ChampionRaceLiteDataResp(
                gameChampionRaceManager.getSpec(),
                gameChampionRaceManager.getSeasonStartTime(),
                gameChampionRaceManager.getNextSeasonStartTime(),
                getNotice(),
                bet.hasBet(gameChampionRaceManager.getSpec()),
                redPacket.hasRedPacket(gameChampionRaceManager.getSpec())
        ));
    }

    @JsonIgnore
    private byte getNotice() {
//        GameChampionRaceManager gameChampionRaceManager = role.getGame().pvp.championRace;
//        if (gameChampionRaceManager.getSpec().getSeason() >= 1 && gameChampionRaceManager.getSpec().getPeriod() < 1 && !notice) {
//            notice = true;
//            return 1;
//        }
        return 0;
    }
}
